package de.hsowl.tod4a.server;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Date;

import de.hsowl.tod4a.global.exception.ObjectDatabaseException;

/**
 * Provides Transaction IDs. Thread safe.
 * 
 * @author Sebastian Witt
 * 
 */
public class TransactionManager {

	public static long transactionID = -1;
	private static File path;

	/**
	 * Generates and saves the next transaction ID
	 * 
	 * @return
	 * @throws ObjectDatabaseException
	 */
	public static synchronized long getNextTransactionId() throws ObjectDatabaseException {
		// id lesen wenn noch nicht getan
		readId();

		transactionID++;
		
		// neue id speichern
		saveId(transactionID);

		return transactionID;
	}

	/**
	 * Saves a transaction id with a timestamp
	 * 
	 * @param id
	 * @throws ObjectDatabaseException
	 */
	public static void saveId(long id) throws ObjectDatabaseException {
		if (path != null) {
			try {
				BufferedWriter bw = new BufferedWriter(new FileWriter(path));
				bw.write(String.valueOf(id) + "\r\n" + (new Date()).toLocaleString());
				bw.flush();
				bw.close();
			} catch (Exception e) {
				throw new ObjectDatabaseException("Fatal Error", e);
			}
		} else {
			throw new ObjectDatabaseException("No path for transaction IDs provided!");
		}
	}

	/**
	 * Reads a transaction id from a file
	 * 
	 * @throws IOException
	 * @throws ObjectDatabaseException
	 */
	private static void readId() throws ObjectDatabaseException {
		// id einlesen
		if (path != null) {
			if (transactionID == -1) {
				try {
					BufferedReader br = new BufferedReader(new FileReader(path));
					String id = br.readLine();
					transactionID = Long.valueOf(id);
					br.close();
				} catch (Exception e) {
					throw new ObjectDatabaseException("Fatal Error", e);
				}
			}
		} else {
			throw new ObjectDatabaseException("No path for transaction IDs provided!");
		}
	}

	/**
	 * Returns the actual transaction id
	 * 
	 * @return
	 */
	public static synchronized long getTransactionId() {
		return transactionID;
	}

	/**
	 * Sets the TransactionManager to default
	 */
	public static void resetTransactionId() {
		transactionID = -1;
	}

	/**
	 * Sets the file to save transaction IDs
	 */
	public static void setTransactionFile(File path) {
		TransactionManager.path = path;
	}

}
